package com.xiaoyu.base.net;

import com.xiaoyu.base.net.request.JsonEventRequest;
import com.xiaoyu.net.request.RequestWithJsonDataReturn;
import com.xiaoyu.base.event.BaseJsonEvent;

import java.io.File;
import java.util.Map;

import in.srain.cube.request.JsonData;
import in.srain.cube.request.RequestData;
import in.srain.cube.request.RequestDefaultHandler;
import in.srain.cube.request.RequestFinishHandler;
import in.srain.cube.request.RequestHandler;
import in.srain.cube.request.RequestJsonHandler;
import in.srain.cube.request.progress.ProgressListener;
import in.srain.cube.views.list.ListPageInfo;

public class RequestCreator<T> {

    private final RequestWithJsonDataReturn<T> mRequestWithJsonDataReturn;
    private final RequestData mRequestData;

    public static <T> RequestCreator<T> create(Class<? extends T> modelClass) {
        return new RequestCreator<>();
    }

    public static <T> RequestCreator<T> create(Object requestTag, Class<? extends BaseJsonEvent> eventClass) {
        return new RequestCreator<>(requestTag, eventClass);
    }

    public static <T> RequestCreator<T> create(Class<? extends T> modelClass, Object requestTag, Class<? extends BaseJsonEvent> eventClass) {
        return new RequestCreator<>(requestTag, eventClass);
    }

    private RequestCreator(Object requestTag, Class<? extends BaseJsonEvent> eventClass) {
        mRequestWithJsonDataReturn = new JsonEventRequest<>(requestTag, eventClass);
        mRequestData = mRequestWithJsonDataReturn.getRequestData();
    }

    private RequestCreator() {
        mRequestWithJsonDataReturn = new RequestWithJsonDataReturn<>();
        mRequestData = mRequestWithJsonDataReturn.getRequestData();
    }

    public RequestCreator<T> method(String method) {
        this.mRequestData.method(method);
        return this;
    }

    public RequestCreator<T> setRequestUrl(String url) {
        this.mRequestData.setRequestUrl(url);
        return this;
    }

    public RequestCreator<T> setPostEventWhenFail(boolean postEventWhenFail) {
        this.mRequestWithJsonDataReturn.setPostEventWhenFail(postEventWhenFail);
        return this;
    }

    public RequestCreator<T> addQueryData(String key, Object data) {
        this.mRequestData.addQueryData(key, data);
        return this;
    }

    public RequestCreator<T> addQueryData(Map<String, ?> data) {
        this.mRequestData.addQueryData(data);
        return this;
    }

    public RequestCreator<T> addQueryData(String key, Object data, boolean isLicensed) {
        if (isLicensed) {
            this.addQueryData(key, data);
        }
        return this;
    }

    public RequestCreator<T> addQueryData(Map<String, ?> data, boolean isLicensed) {
        if (isLicensed) {
            this.addQueryData(data);
        }
        return this;
    }

    public RequestCreator<T> addPostData(String key, Object data) {
        this.mRequestData.addPostData(key, data);
        return this;
    }

    public RequestCreator<T> addPostData(Map<String, ?> data) {
        this.mRequestData.addPostData(data);
        return this;
    }

    public RequestCreator<T> addPostData(String key, Object data, boolean isLicensed) {
        if (isLicensed) {
            this.addPostData(key, data);
        }
        return this;
    }

    public RequestCreator<T> addPostData(Map<String, ?> data, boolean isLicensed) {
        if (isLicensed) {
            this.addPostData(data);
        }
        return this;
    }

    public RequestCreator<T> appendQueryDataTo(ListPageInfo listPageInfo) {
        listPageInfo.appendQueryDataTo(mRequestData);
        return this;
    }

    public RequestCreator<T> appendPostDataTo(ListPageInfo listPageInfo) {
        listPageInfo.appendQueryDataTo(mRequestData);
        return this;
    }

    public RequestCreator<T> addFile(String fieldName, String uploadFile) {
        this.mRequestData.addFile(fieldName, uploadFile);
        return this;
    }

    public RequestCreator<T> addFile(String fieldName, String uploadFile, String fileName) {
        this.mRequestData.addFile(fieldName, uploadFile, fileName);
        return this;
    }

    public RequestCreator<T> addFile(String fieldName, File uploadFile) {
        this.mRequestData.addFile(fieldName, uploadFile);
        return this;
    }

    public RequestCreator<T> addFile(String fieldName, File uploadFile, String fileName) {
        this.mRequestData.addFile(fieldName, uploadFile, fileName);
        return this;
    }

    public RequestCreator<T> setProgressListener(ProgressListener progressListener) {
        this.mRequestData.setProgressListener(progressListener);
        return this;
    }

    public RequestCreator<T> setRequestHandler(RequestDefaultHandler<T, JsonData> requestDefaultHandler) {
        this.mRequestWithJsonDataReturn.setRequestHandler(requestDefaultHandler);
        return this;
    }

    @SuppressWarnings("all")
    public RequestCreator<T> setRequestHandler(RequestJsonHandler requestJsonHandler) {
        this.mRequestWithJsonDataReturn.setRequestHandler((RequestDefaultHandler<T, JsonData>) requestJsonHandler);
        return this;
    }

    public RequestCreator<T> setRequestHandler(RequestHandler<T, JsonData> requestHandler) {
        this.mRequestWithJsonDataReturn.setRequestHandler(requestHandler);
        return this;
    }

    public RequestCreator<T> setRequestHandler(RequestFinishHandler<T> requestFinishHandler) {
        this.mRequestWithJsonDataReturn.setRequestFinishHandler(requestFinishHandler);
        return this;
    }

    public RequestCreator<T> setRequestHandler(RequestFinishHandler<T> requestFinishHandler, RequestHandler<T, JsonData> requestHandler) {
        this.mRequestWithJsonDataReturn.setRequestHandler(requestFinishHandler, requestHandler);
        return this;
    }

    public RequestCreator<T> enqueue() {
        this.mRequestWithJsonDataReturn.enqueue();
        return this;
    }

    public RequestCreator<T> requestSync() throws Throwable {
        this.mRequestWithJsonDataReturn.requestSync();
        return this;
    }
}
